/*
File      : ServerImplementation.java - This is an implementation of all interface functions defined in ServerInterface.java
            It provides all the methods needed to communicate with the client.
Author    : Kunal Cholera.
Project 4 : Group Chat Application using Java RMI - Remote Method Invocation.
Course    : Distributed Systems.
Institute : University of Southern California - Viterbi School of Engineering.

*/

import java.rmi.*;
import java.rmi.server.*;
import java.util.Vector;
import java.awt.List;

public class ServerImplementation extends UnicastRemoteObject implements ServerInterface{
	
	private Vector clientList;
	//private static List loggedInUsers = new List();
	
	private static String loginMenu = "************** GROUP CHAT RMI APPLICATION Menu *********\n\n" +
	 									"1. Create an Account\n" +
										"2. Login using Existing Account\n" +
										"0. Quit\n" +
									
										"Enter Option 1 or 2\n\n";
	
	private static String mainMenu = "************** GROUP CHAT RMI APPLICATION Menu *********\n\n" +
	                                 "1. Create an Account\n" +
                             		 "2. Login using Existing Account\n" +
	                                 "3. List all accounts & all Live Users \n"+
       	                             "4. Group Chat : With all Live Users !! \n"+
	                                 "0. Logg Out/Quit\n" +
                               		"********************************\n" +"\nEnter your Selection Number :";
	
	private Vector accounts = new Vector();
	private static Vector loggedInUsers = new Vector();
	                       
	
	public ServerImplementation() throws RemoteException{
		super();
		clientList = new Vector();
	}//end constructor
	
	public String sayHello( String userName) throws java.rmi.RemoteException{
		return "Hello -" + userName;
	}//end sayHello
	
	//part of service 5
	public void registerForCallback( ClientInterface callbackClientObject ) throws java.rmi.RemoteException{
		if(!(clientList.contains(callbackClientObject))){
			clientList.addElement( callbackClientObject );
			System.out.println("New Client Registered...");
			//doCallbacks(" ");
		}
		
	}//end registerForCallback
	
	//part of service 6
	public void floodMessage( String message ) throws java.rmi.RemoteException{
		doCallbacks(message);
		
	}
	
	
	// Service 5 and 6 - Used to emulate the effect of Multicast IP address where in all the messages are sent to all clients....
	// Used form the Advanced RMI chapter of the text book to emulate Group Chat application...
	public synchronized void unregisterForCallback( ClientInterface callbackClientObject ) throws java.rmi.RemoteException{
		if(clientList.removeElement( callbackClientObject )){
			System.out.println("Client Unregistered");
		}else{
			System.out.println("Unknown Client");
		}
		
	}//end unregisterForCallback
	
	private synchronized void doCallbacks( String message ) throws java.rmi.RemoteException{
		for(int i= 0; i< clientList.size(); i++){
			ClientInterface nextClient = (ClientInterface)clientList.elementAt(i);
			nextClient.notifyClient( message );
			//System.out.println("CLIENT ID : " + nextClient.getClientId() );
			//nextClient.notifyClient("Number of registered Clients = " + clientList.size());
		}
		System.out.println("Message Flodding complete...");
	}//end doCallbacks()

    // Service 2 - Loggs all existing account holders in and also loggs all the users out when they press 0	
	public Boolean login( String userName ) throws java.rmi.RemoteException{
		loggedInUsers.addElement( userName );
		System.out.println( userName + " logg in Success ");
		System.out.println("Total number of Logged In Users : " + loggedInUsers.size() );
		return true;
	}
	
	// Service 2 - Loggs all existing account holders in and also loggs all the users out when they press 0
	public Boolean logout( String userName ) throws java.rmi.RemoteException{
		loggedInUsers.removeElement( userName );
		System.out.println( userName + " logg out Suceess");
		System.out.println("Total number of Logged Out Users : " +  loggedInUsers.size() );
		return true;
	}
    
    // Service 4 - Displays the menu - two types, the one used during the login process, check if valid user and then logs user
    //used in all services....
    public String displayMenu( String menuType) throws java.rmi.RemoteException{
	  if( menuType.equalsIgnoreCase("loginMenu")){
		return loginMenu;
	  }else if( menuType.equalsIgnoreCase("mainMenu")){
		  System.out.println("Menu sent");
	      return mainMenu;
	  }

    return "Invalid Arguments to displayMenu function";
    }//end displayMenu
	
	// Service 2 - Loggs all existing account holders in and also loggs all the users out when they press 0
	public Boolean checkLoginName( String userName ) throws java.rmi.RemoteException{
		if (accounts.contains(userName))
		 return true;
		else return false;
	}

    // Service number 1 -> Creates an Account for the entered username	
	public Boolean createAccount( String userName )throws java.rmi.RemoteException{
		accounts.addElement( userName );
		System.out.println("Account Created");
		System.out.println("Total Acconts : " + accounts.size());
		loggedInUsers.add( userName );
		System.out.println("User Logged in Succes");;
		return true;
		
	}
	
	// loop through all accounts and loggedin user datastructure and form the string..
	// Service number 3 -> shows all valid user accounts and shows all Live Users of Group chat Application
	public String showUserStatus() throws java.rmi.RemoteException{
		return "\n\n\nActive Accounts : "+ accounts.toString() + "\nLIVE Users : " + loggedInUsers.toString() + "\n\n\n"; 
	}

}//end ServerImplementation

